package com.wd.jetpack.helper.exytens;

import androidx.databinding.ObservableField
import androidx.lifecycle.*
import com.uber.autodispose.AutoDispose
import com.uber.autodispose.SingleSubscribeProxy
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider
import io.reactivex.BackpressureStrategy
import io.reactivex.Flowable
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.android.MainThreadDisposable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit

/**
 * 页面描述：Model 和ViewModel层的一些扩展
 */

////////////////////////////////////////RxJava扩展////////////////////////////////////////
fun <T> Flowable<T>.async(withDelay: Long = 0): Flowable<T> =
        this.subscribeOn(Schedulers.io()).delay(withDelay, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread())

fun <T> Single<T>.async(withDelay: Long = 0): Single<T> = if (withDelay > 0) {
  this.subscribeOn(Schedulers.io()).delay(withDelay, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread())
} else {
  this.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
}

////////////////////////////////////////LiveData扩展////////////////////////////////////////

fun <T> Single<T>.bindLifeCycle(owner: LifecycleOwner): SingleSubscribeProxy<T> =
        this.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(owner, Lifecycle.Event.ON_DESTROY)))


fun <T> LiveData<T>.toFlowable(): Flowable<T> = Flowable.create({ emitter ->
  val observer = Observer<T> { data ->
    data?.let { emitter.onNext(it) }
  }
  observeForever(observer)

  emitter.setCancellable {
    object : MainThreadDisposable() {
      override fun onDispose() = removeObserver(observer)
    }
  }
}, BackpressureStrategy.LATEST)

fun <T : Any> MutableLiveData<T>.set(value: T?) = postValue(value)

fun <T : Any> MutableLiveData<T>.get(): T = this!!.value!!

fun <T : Any> MutableLiveData<T>.get(instance: () -> T): T = if (value == null) instance() else get()

fun <T : Any> MutableLiveData<T>.init(t: T? = null) = MediatorLiveData<T>().apply {
  set(t)
}

fun <T : Any> ObservableField<T>.toObservable() = Observable.create<T> {
  this.addOnPropertyChangedCallback(object : androidx.databinding.Observable.OnPropertyChangedCallback() {
    override fun onPropertyChanged(sender: androidx.databinding.Observable?, propertyId: Int) {
      this@toObservable.get()?.let { result ->
        it.onNext(result)
      }
    }

  })
}

/////////////////////////////////////Json///////////////////////////////////////
//转换obj to json String
